package org.footballmanager.pandafootball.system.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.footballmanager.pandafootball.common.constants.Constants;
import org.footballmanager.pandafootball.system.dao.FootTtDao;
import org.footballmanager.pandafootball.system.domain.*;
import org.footballmanager.pandafootball.system.form.impl.FootTtSearchForm;
import org.footballmanager.pandafootball.system.mapper.FootTtMapper;
import org.footballmanager.pandafootball.system.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Random;

@Slf4j
@Service
public class FootTtServiceImpl extends RepeatMainServiceImpl<FootTt> implements FootTtService {
    protected static final double TOP1 = 100D;
    protected static final double TOP2 = 80D;
    protected static final double TOP3 = 50D;

    @Autowired
    private FootTtMapper footTtMapper;
    @Autowired
    private FootTtDao footTtDao;
    @Autowired
    private FootUserService footUserService;
    @Autowired
    private FootUserPersonService footUserPersonService;
    @Autowired
    private FootTeamService footTeamService;
    @Autowired
    private FootSjService footSjService;
    @Autowired
    private FootChipService footChipService;

    /**
     * 获取天梯赛积分榜
     *
     * @return 天梯赛积分榜
     */
    @Override
    public List<FootTt> getScoreboard() {
        Example example = new Example(FootTt.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", footSjService.getSj());
        criteria.andEqualTo("delFlag", 0);
        example.orderBy("jf").desc();
        List<FootTt> list = findall(example);
        if (list != null && !list.isEmpty()) {
            return list;
        } else {
            return Collections.emptyList();
        }
    }

    /**
     * 根据用户主键获取记录
     *
     * @param userId 用户主键
     * @return 记录
     */
    @Override
    public FootTt findByUserid(Long userId) {
        Example example = new Example(FootTt.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo(Constants.USERID, userId);
        criteria.andEqualTo("sj", footSjService.getSj());
        criteria.andEqualTo("delFlag", 0);
        FootTt ft = this.findByExample(example);
        if (ft != null) {
            return ft;
        }
        return null;
    }

    /**
     * 重新计算排名
     *
     * @param request 请求
     */
    @Override
    @Transactional
    public void reComputeRanking(HttpServletRequest request) {
        List<FootTt> list = this.getScoreboard();
        if (null != list && !list.isEmpty()) {
            int i = 1;
            for (FootTt ft : list) {
                ft.setPm(i++);
                if (request != null) {
                    ft.setUpdateId((Long) request.getSession().getAttribute(Constants.USERID));
                } else {
                    ft.setUpdateId(1L);
                }
                ft.setUpdateTime(new Date());
                footTtDao.updateByPrimaryKeySelective(ft);
            }
        }
    }

    /**
     * 根据用户主键查找对应所有的天梯赛信息
     *
     * @param userId 用户主键
     * @return 天梯赛信息列表
     */
    @Override
    public List<FootTt> getTtsByUserid(Long userId) {
        Example example = new Example(FootTt.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo(Constants.USERID, userId);
        criteria.andEqualTo("delFlag", 0);
        return this.findall(example);
    }

    /**
     * 添加新的天梯赛到数据库
     *
     * @param user    用户实体类
     * @param qdId    球队主键
     * @param request 请求
     */
    @Override
    public void saveNewTt(FootUser user, Long qdId, HttpServletRequest request) {
        FootTt ft = new FootTt();
        ft.setQdId(qdId);
        ft.setBscc(0);
        ft.setS(0);
        ft.setF(0);
        ft.setP(0);
        ft.setJf(0);
        ft.setUserId(user.getId());
        ft.setSj(footSjService.getSj());
        this.save(ft, request);
    }

    /**
     * 更新天梯赛的球队名称
     *
     * @param userId  用户主键
     * @param qd      球队实体类
     * @param request 请求
     */
    @Override
    public void updateTtQdName(Long userId, FootQd qd, HttpServletRequest request) {
        FootTt t = this.findByUserid(userId);
        if (null != t) {
            t.setQdId(qd.getId());
            this.updateNotNull(t, request);
        }
    }

    /**
     * 发放天梯赛的奖励
     *
     * @param request 请求
     */
    @Override
    public void reward(HttpServletRequest request) {
        List<FootTt> list = this.getScoreboard();
        if (!list.isEmpty()) {
            //第一名
            FootTt t1 = list.get(0);
            if (null != t1) {
                this.rewardTop3(t1, "一", request);
            }
        }
        if (list.size() > 1) {
            //第二名
            FootTt t2 = list.get(1);
            if (null != t2) {
                this.rewardTop3(t2, "二", request);
            }
        }
        if (list.size() > 2) {
            //第三名
            FootTt t3 = list.get(2);
            if (null != t3) {
                this.rewardTop3(t3, "三", request);
            }
        }
    }

    /**
     * 发放前三名奖励
     *
     * @param t       天梯赛实体类
     * @param top     汉子Top
     * @param request 请求
     */
    private void rewardTop3(FootTt t, String top, HttpServletRequest request) {
        /*
         * 碎片发放
         * 最后排名
         * 第一  100  3个橙色碎片
         * 第二  80   2个橙色碎片
         * 第三  50   1个橙色碎片
         */
        if (t != null) {
            FootChip fc = footChipService.findChipByUserId(t.getUserId());
            FootTeam team = footTeamService.getTeamByUserid(t.getUserId());
            double money = 0D;
            switch (top) {
                case "一":
                    money = TOP1;
                    fc.setHaveOrange(fc.getHaveOrange() + 3);
                    break;
                case "二":
                    money = TOP2;
                    fc.setHaveOrange(fc.getHaveOrange() + 2);
                    break;
                case "三":
                    money = TOP3;
                    fc.setHaveOrange(fc.getHaveOrange() + 1);
                    break;
                default:
                    break;
            }
            footChipService.updateNotNull(fc, request);

            team.setQdZzj(team.getQdZzj() + money);
            String result = "恭喜您,获得天梯赛第" + top + "名,发放奖金:" +
                    new DecimalFormat(",###").format(money) + "PB,当前总资金为:" +
                    new DecimalFormat(",###").format(team.getQdZzj()) + "PB";
            team.setYy(result);
            footTeamService.updateNotNull(team, request);
        }
    }

    /**
     * 根据对战双方的主力战斗力算出胜负
     *
     * @param userId1 主队用户主键
     * @param userId2 客队用户主键
     * @param request 请求
     * @return true user1获胜 false user2获胜 null 平手
     */
    @Override
    public String winner(Long userId1, Long userId2, HttpServletRequest request) {
        Double user1;
        Double user2;
        int userResult1;
        int userResult2 = 0;

        int zhulist = footUserPersonService.checkMainPerson(footUserService.get(userId1));
        int kelist = footUserPersonService.checkMainPerson(footUserService.get(userId2));
        if (zhulist >= 18 && kelist >= 18) {
            user1 = footUserPersonService.getPower(userId1, request);
            user2 = footUserPersonService.getPower(userId2, request);

            user1 = randomNumber(user1);
            user2 = randomNumber(user2);
            //可以打平，但不能高于战斗力高的那支队伍
            Random r = new Random();
            if (user1.equals(user2)) {
                userResult1 = r.nextInt(5);
            } else if (user1 > user2) {
                int result = r.nextInt(5) + 1;
                int s = r.nextInt(result);
                userResult1 = result;
                userResult2 = s;
            } else {
                int result = r.nextInt(5) + 1;
                userResult1 = r.nextInt(result);
                userResult2 = result;
            }
            return userResult1 + ":" + userResult2;
        } else {
            return Constants.ERROR;
        }
    }

    /**
     * 获取随机数
     *
     * @param num 数字
     * @return 随机数
     */
    private double randomNumber(double num) {
        //处理状态问题 1.05   1    0.95
        double result = num;
        Random r1 = new Random();
        int result1 = r1.nextInt(3);
        if (result1 == 1) {
            result = num * 1.05D;
        } else if (result1 == 2) {
            result = num * 0.95D;
        }
        return result;
    }

    /**
     * 查找是否有重复数据
     *
     * @param footTt 天梯赛实体类
     * @return 是否重复
     */
    @Override
    public boolean findRepeatData(FootTt footTt) {
        Example example = new Example(FootTt.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("qdId", footTt.getQdId());
        criteria.andEqualTo(Constants.USERID, footTt.getUserId());
        criteria.andEqualTo("sj", footTt.getSj());
        criteria.andEqualTo("delFlag", 0);
        List<FootTt> list = this.findall(example);
        return null != list && !list.isEmpty();
    }

    /**
     * 翻页方法
     *
     * @param footTtSearchForm 条件
     * @return 列表
     */
    @Override
    public List<FootTt> findall(FootTtSearchForm footTtSearchForm) {
        return footTtMapper.findall(footTtSearchForm);
    }

    /**
     * 根据主键获取记录
     *
     * @param id 主键
     * @return 记录
     */
    @Override
    public FootTt get(Serializable id) {
        return footTtMapper.findById(id);
    }

    /**
     * 查询
     *
     * @param entityname       实体类名
     * @param map              参数
     * @param footTtSearchForm 条件
     */
    @Override
    public void search(String entityname, Model map, FootTtSearchForm footTtSearchForm) {
        map.addAttribute(String.format(Constants.FORMNAME, entityname), footTtSearchForm);
        Page<FootTt> page = PageHelper.startPage(footTtSearchForm.getPageIndex(), footTtSearchForm.getPageSize());
        List<FootTt> list = this.findall(footTtSearchForm);
        map.addAttribute(Constants.PI, page.toPageInfo());
        map.addAttribute(String.format(Constants.LISTENTITY, entityname), list);
    }

    /**
     * 补全本赛季没有加入的玩家
     *
     * @param sjId 赛季主键
     */
    @Override
    public void processFixBySj(Long sjId) {
        List<FootUser> list = footUserService.getAllWithoutAdmin(null);
        if (list == null || list.isEmpty()) {
            return;
        }
        for (FootUser footUser : list) {
            FootTt tt = findByUserIdAndSj(footUser.getId(), sjId);
            if (tt == null && footUser.getJoins()) {
                FootTt oldTt = findByUserIdAndSj(footUser.getId(), footSjService.getLastSj());
                if (oldTt != null) {
                    FootTt newTt = new FootTt();
                    BeanUtils.copyProperties(oldTt, newTt);
                    newTt.setId(null);
                    newTt.setSj(sjId);
                    this.save(newTt, null);
                } else {
                    this.saveNewTt(footUser, null, null);
                }
            }
        }
    }

    /**
     * 根据用户主键和赛季主键获取天梯赛记录
     *
     * @param userId 用户主键
     * @param sjId   赛季主键
     * @return 天梯赛记录
     */
    private FootTt findByUserIdAndSj(Long userId, Long sjId) {
        Example example = new Example(FootTt.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andEqualTo("sj", sjId);
        criteria.andEqualTo("delFlag", 0);
        return this.findByExample(example);
    }

    /**
     * 根据用户主键删除对应记录
     *
     * @param userId  用户主键
     * @param request 请求
     */
    @Override
    public void deleteByUserId(Long userId, HttpServletRequest request) {
        //删除Tt信息
        List<FootTt> ttList = this.getTtsByUserid(userId);
        if (ttList != null && !ttList.isEmpty()) {
            for (FootTt tt : ttList) {
                this.delete(tt.getId(), request);
            }
        }
    }
}
